package main

/// https://systembash.com/a-simple-go-tcp-server-and-tcp-client/
// this go exec file is for test purpose, will act as GPRS model in IFMS

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"os"
	"regexp"
	"strings"
)

func main() {
	// var text string
	remoteIp := "localhost" //"120.76.151.52"
	remotePort := "8080"    // "9721"

	if len(os.Args) > 1 && (os.Args[1] == "localhost" || regexp.MustCompile(`^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$`).MatchString(os.Args[1])) {
		remoteIp = os.Args[1]
	}

	if len(os.Args) > 2 && regexp.MustCompile(`^[0-9]{2,4}$`).MatchString(os.Args[2]) {
		remotePort = os.Args[2]
	}

	remoteAddr := remoteIp + ":" + remotePort
	// remoteAddr := "192.168.0.102:1234"
	//	remoteAddr := "localhost:1234"
	loopFlag := true
	// svrEcho := true

	//下行数据帧内容如下：#;<1>;<2>;<3>;;
	// validID := regexp.MustCompile(`^#;.{15};1;[0-9]{4},[01][0-9],[0-3][0-9],[0-2][0-9],[0-5][0-9],[0-5][0-9]`)

	fmt.Print("Dailing to :", remoteAddr, "......")

	conn, err := net.Dial("tcp", remoteAddr)

	if err != nil {
		fmt.Printf("Dial fail: %s\n", err.Error())
		return
	}

	defer conn.Close()

	fmt.Printf("\nConnected to : %v\n", conn.RemoteAddr())

	c := chanFromConn(conn)
	reader := bufio.NewReader(os.Stdin)
	r := chanFromConn(reader)

outerLoop:
	for loopFlag {

		select {
		case msg := <-c:
			fmt.Printf("Received From Server:%v\n", string(msg[:]))

		case text := <-r:

			// input  := fmt.Sprintf("%v", text)
			input := strings.TrimSpace(string(text[:])) // strings.TrimSpace(strings.ToUpper( string(text[:])  ))

			fmt.Println("inputed:", input)

			switch strings.ToUpper(input) {
			case "EXIT":
				loopFlag = false
				break outerLoop
			case "E":
				loopFlag = false
				break outerLoop
			case "QUIT":
				loopFlag = false
				break outerLoop
			case "Q":
				loopFlag = false
				break outerLoop
			case "":
				loopFlag = false
				fmt.Print("No Input")
				break outerLoop
			}
			fmt.Fprintf(conn, input+"\n")

		}

	}

}

//func chanFromConn( conn net.Conn) chan [] byte {
func chanFromConn(conn io.Reader) chan []byte {
	c := make(chan []byte)

	go func() {
		b := make([]byte, 1024)

		for {
			n, err := conn.Read(b)

			if n > 0 {

				res := make([]byte, n)
				copy(res, b[:n])

				c <- res

			}
			if err != nil {
				c <- nil
				break
			}
		}
	}()

	return c

}
